﻿using SharpGL;

using System;
using System.Windows.Forms;

namespace UCTT.GL
{
    /// <summary>
    /// 原文链接：三、SharpGL的功能应用--图形绘制 - 卢大鸽 - 博客园
    /// https://www.cnblogs.com/ludage/p/12884144.html
    /// </summary>
    public partial class Form2 : Form
    {
        #region       变量/常量 start
        private bool drawLine = false;
        private bool drawArea = false;
        private bool drawVolume = false;
        private bool flagRotateX = false;
        private bool flagRotateY = false;
        private bool flagRotateZ = false;
        private float rotation_X = 0.0f;
        private float rotation_Y = 0.0f;
        private float rotation_Z = 0.0f;
        #endregion 变量/常量 end

        #region       构造/析构函数 start
        public Form2()
        {
            InitializeComponent();
        }
        #endregion 构造/析构函数 end

        #region       事件处理 start

        private void oglc_Container_OpenGLInitialized(object sender, EventArgs e)
        {
            OpenGL gl = oglc_Container.OpenGL;
            gl.ClearColor(0, 0, 0, 0);
        }

        private void oglc_Container_Resize(object sender, EventArgs e)
        {
            OpenGL gl = oglc_Container.OpenGL;

            // 设置当前矩阵模式,对投影矩阵应用随后的矩阵操作
            gl.MatrixMode(OpenGL.GL_PROJECTION);

            // 重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心
            gl.LoadIdentity();

            // 创建透视投影变换
            gl.Perspective(30.0f, (double)Width / (double)Height, 5, 100.0);

            // 视点变换
            gl.LookAt(0, 5, 0, 0, 0, 0, 0, 1, 0);

            // 设置当前矩阵为模型视图矩阵
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }

        /// <summary>
        /// OpenGL绘图事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void oglc_Container_OpenGLDraw(object sender, RenderEventArgs args)
        {
            OpenGL gl = oglc_Container.OpenGL;
            //清除深度缓存 
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            //重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心
            gl.LoadIdentity();

            //坐标轴变换位置到(0.0f, 0.0f, -5.0f)，这样我们的坐标轴就相当于往屏幕内走5个单位
            gl.Translate(0.0f, 0.0f, -5.0f);

            if (flagRotateX)
            {
                rotation_X += 1f;
                gl.Rotate(rotation_X, 1.0f, 0.0f, 0.0f);//rotationX:角度
            }
            if (flagRotateY)
            {
                rotation_Y += 1f;
                gl.Rotate(rotation_Y, 0.0f, 1.0f, 0.0f);//rotationY:角度
            }
            if (flagRotateZ)
            {
                rotation_Z += 1f;
                gl.Rotate(rotation_Z, 0.0f, 0.0f, 1.0f);//rotationZ:角度
            }

            if (drawLine)
            {
                #region 点到线
                gl.Begin(OpenGL.GL_LINES);
                gl.Color(1.0f, 1.0f, 1.0f);
                gl.Vertex(-2.0f, 0.0f, 0.0f);//左顶点
                gl.Vertex(2.0f, 2.0f, 0.0f);//右顶点
                gl.End();
                #endregion
            }
            if (drawArea)
            {
                #region 线成面(三角形)
                gl.Begin(OpenGL.GL_TRIANGLES);//第一个面
                gl.Color(1.0f, 0.0f, 0.0f);
                gl.Vertex(0.0f, 1f, 0.0f);//顶点
                gl.Color(0.0f, 1.0f, 0.0f);
                gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点 
                gl.Color(0.0f, 0.0f, 1.0f);
                gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
                gl.End();
                #endregion
            }
            if (drawVolume)
            {
                #region 面组合成体
                gl.Begin(OpenGL.GL_TRIANGLES);//第二个面
                gl.Color(1.0f, 1.0f, 1.0f);
                gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
                gl.Color(0.0f, 1.0f, 0.0f);
                gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点 
                gl.Color(0.0f, 0.0f, 1.0f);
                gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
                gl.End();
                gl.Begin(OpenGL.GL_TRIANGLES);//第三个面
                gl.Color(1.0f, 1.0f, 1.0f);
                gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
                gl.Color(0.0f, 1.0f, 0.0f);
                gl.Vertex(-1.0f, -1.0f, 0.0f);//左顶点 
                gl.Color(1.0f, 0.0f, 0.0f);
                gl.Vertex(0.0f, 1f, 0.0f);//顶点
                gl.End();
                gl.Begin(OpenGL.GL_TRIANGLES);//第四个面
                gl.Color(1.0f, 1.0f, 1.0f);
                gl.Vertex(0.0f, 0.0f, -2.0f);//第四个点
                gl.Color(0.0f, 0.0f, 1.0f);
                gl.Vertex(1.0f, -1.0f, 0.0f);//右顶点
                gl.Color(1.0f, 0.0f, 0.0f);
                gl.Vertex(0.0f, 1f, 0.0f);//顶点
                gl.End();
                #endregion
            }

            gl.Flush();   //强制刷新
        }

        
        private void ckb_DrawLine_CheckedChanged(object sender, EventArgs e)
        {
            drawLine = this.ckb_DrawLine.Checked;
        }

        private void ckb_DrawArea_CheckedChanged(object sender, EventArgs e)
        {
            drawArea = this.ckb_DrawArea.Checked;
        }

        private void ckb_DrawVolume_CheckedChanged(object sender, EventArgs e)
        {
            drawVolume = this.ckb_DrawVolume.Checked;
        }

        private void ckb_RotateX_CheckedChanged(object sender, EventArgs e)
        {
            flagRotateX = this.ckb_RotateX.Checked;
        }

        private void ckb_RotateY_CheckedChanged(object sender, EventArgs e)
        {
            flagRotateY = this.ckb_RotateY.Checked;
        }

        private void ckb_RotateZ_CheckedChanged(object sender, EventArgs e)
        {
            flagRotateZ = this.ckb_RotateZ.Checked;
        }
        #endregion 事件处理 end
    }
}
